package com.ibm.cloud.banking.parameter.pricing.service;

import com.ibm.cloud.banking.parameter.pricing.entity.*;
import com.ibm.cloud.banking.parameter.pricing.facade.IBaseRateLyrDefineService;
import com.ibm.cloud.banking.parameter.pricing.facade.IFeeCfrmRuleService;
import com.ibm.cloud.banking.parameter.pricing.facade.IPricingChargingInnerService;
import com.ibm.cloud.banking.parameter.pricing.facade.IPricingCommonService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 计收费(汇总收费)服务接口(定价内部使用)
 *
 * @author Administrator
 *
 */
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = RuntimeException.class)
public class PricingChargingInnerServiceImpl implements IPricingChargingInnerService {

    @Autowired
    private IFeeCfrmRuleService feeCfrmRuleService; // 费用确定规则服务接口

    @Autowired
    private IBaseRateLyrDefineService baseRateLyrDefineService; // 基础费率分层定义服务接口

    @Autowired
    private IPricingCommonService pricingCommonService; // 费用处理通用服务接口

    static final Logger logger =LoggerFactory.getLogger(PricingChargingInnerServiceImpl.class);
    
    public ResultVo<PricingChargeResultVo> pricingChargingService(PricingChargeParamVo pricingChargeParamVo)
            throws BizException {
        String tipMsg = ""; // 错误提示信息
        /**
         * 定义返回的resutlVo
         */
        ResultVo<PricingChargeResultVo> resultVo = new ResultVo<PricingChargeResultVo>();
        resultVo.setResultCode("00000");
        resultVo.setResultMsg("成功!");
        resultVo.setData(null);
        /**
         * 定义返回的结果data数据Vo
         */
        ChargeFeeResultVo chargeFeeResultVo = null;
        List<ChargeFeeResultVo> chargeFeeResultVoList = new ArrayList<ChargeFeeResultVo>(); // 收费信息返回Vo
        PricingChargeResultVo pricingChargeResultVo = new PricingChargeResultVo(); // 定义返回Vo
        /**
         * 检验参数
         */
        if (StringUtils.isEmpty(pricingChargeParamVo.getChargeFlag())) {
            tipMsg = "[入参chargeFlag为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(pricingChargeParamVo.getJiFeiItemVo())) {
            tipMsg = "[入参计费资料为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        // 计费资料Vo
        JiFeiItemVo jiFeiItemVo = pricingChargeParamVo.getJiFeiItemVo();
        if (StringUtils.isEmpty(jiFeiItemVo.getBillgCcyCode())) {
            tipMsg = "[计费资料->计费币种为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(jiFeiItemVo.getChbz())) {
            tipMsg = "[计费资料->钞汇标志为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        // 收费资料
        ShouFeiItemVo shouFeiItemVo = pricingChargeParamVo.getShouFeiItemVo();
        if (StringUtils.isEmpty(shouFeiItemVo)) {
            tipMsg = "[入参收费资料为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(shouFeiItemVo.getXzbz())) {
            tipMsg = "[入参现转标志为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        // 业务场景入参Vo
        BusinessSceneInfoVo businessSceneInfoVo = pricingChargeParamVo.getBusinessSceneInfoVo();
        if (StringUtils.isEmpty(businessSceneInfoVo)) {
            tipMsg = "[入参业务场景为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(businessSceneInfoVo.getTransOrgNo())) {
            tipMsg = "[入参交易发起机构为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(businessSceneInfoVo.getTransDate())) {
            tipMsg = "[入参交易日期机构为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(businessSceneInfoVo.getTransTime())) {
            tipMsg = "[入参交易时间机构为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        if (StringUtils.isEmpty(businessSceneInfoVo.getTransPersonCode())) {
            tipMsg = "[入参交易柜员编号为空]";
            logger.info(tipMsg);
            throw new BizException("90001", tipMsg);
        }
        /**
         * 调用业务构件BFEPDCS0’决定费率种类’
         */
        FeeCurrenyCodeVo feeCurrenyCodeVo = pricingChargeParamVo.getFeeCurrenyCodeVo();
        String feeCodeParam = null;
        if (!StringUtils.isEmpty(feeCurrenyCodeVo) && !StringUtils.isEmpty(feeCurrenyCodeVo.getFeeCode())) {
            feeCodeParam = feeCurrenyCodeVo.getFeeCode();
        }
        ResultVo<List<PrpFeeCfrmRule>> prpFeeCfrmRuleListResultVo = new ResultVo<List<PrpFeeCfrmRule>>();
        List<PrpFeeCfrmRule> prpFeeCfrmRuleResultVoList = new ArrayList<PrpFeeCfrmRule>();
        PrpFeeCfrmRule prpFeeCfrmRule = null;
        // 如果In.费用代码不等于空，则out.费用代码[1] =In .费用代码
        if (!StringUtils.isEmpty(feeCodeParam)) {
            prpFeeCfrmRule = new PrpFeeCfrmRule();
            prpFeeCfrmRule.setFeeCode(feeCodeParam);
            prpFeeCfrmRuleResultVoList.add(prpFeeCfrmRule);
            prpFeeCfrmRuleListResultVo.setData(prpFeeCfrmRuleResultVoList);
        } else {
            // 如果In.费用代码 等于空，则调用业务构件BFEPDCS0’决定费率种类’
            // 设置查询参数
            prpFeeCfrmRule = new PrpFeeCfrmRule();
            // prpFeeCfrmRule.setAvlSellPdNum(businessSceneInfoVo.getSaleProductNo());
            // // 可售产品编号=In.可售产品编号
            prpFeeCfrmRule.setValnTxnCode(businessSceneInfoVo.getTransCode()); // 交易码=In.交易编码
            // 根据条件查询决定费率种类
            prpFeeCfrmRuleListResultVo = feeCfrmRuleService.findFeeCodeOfFeeCfrmRuleByCondition(prpFeeCfrmRule);
        }
        if (StringUtils.isEmpty(prpFeeCfrmRuleListResultVo)
                || StringUtils.isEmpty(prpFeeCfrmRuleListResultVo.getData())) {
            tipMsg = "[没有查询到决定费率种类]";
            logger.info("[根据条件查询决定费率种类，沒有查询到决定费率种类]!");
            throw new BizException("90001", tipMsg);
        }
        List<PrpFeeCfrmRule> prpFeeCfrmRuleList = prpFeeCfrmRuleListResultVo.getData();
        BaseRateLyrDefineParamVo baseRateLyrDefineParamVo = null;
        BigDecimal totalFeeAmount = new BigDecimal("0"); // 总收费金额
        BigDecimal totalZzsAmount = new BigDecimal("0"); // 总增值税金额
        BigDecimal totalShAmount = new BigDecimal("0"); // 总税后收费金额
        for (PrpFeeCfrmRule prpFeeCfrmRuleResultVo : prpFeeCfrmRuleList) {
            /**
             * 费用代码 = out.费用代码[n]， 计费币种代码 = in.计费币种， 钞汇标志 = In.钞汇标志， 定价机构 =
             * In.交易发起机构， 交易日期 = In.交易日期 交易时间 = In.交易时间）， 客户号 = In.客户号， 账号 =
             * In.客户账号， 交易金额 = In.交易金额，
             *
             */
            baseRateLyrDefineParamVo = new BaseRateLyrDefineParamVo();
            baseRateLyrDefineParamVo.setFeeCode(prpFeeCfrmRuleResultVo.getFeeCode()); // 费种代码=out.费种代码[n]
            baseRateLyrDefineParamVo.setCurrencyCode(jiFeiItemVo.getBillgCcyCode()); // 计费币种代码=in.计费币种
            baseRateLyrDefineParamVo.setChbz(jiFeiItemVo.getChbz()); // 钞汇标志=In.钞汇标志
            baseRateLyrDefineParamVo.setPricingOrgNo(businessSceneInfoVo.getTransOrgNo()); // 交易机构
            baseRateLyrDefineParamVo.setTransDate(businessSceneInfoVo.getTransDate()); // 交易日期=In.交易日期
            baseRateLyrDefineParamVo.setTransTime(businessSceneInfoVo.getTransTime()); // 交易时间=In.交易时间
            baseRateLyrDefineParamVo.setTransAmount(businessSceneInfoVo.getTransAmount()); // 交易金额=In.交易金额
            baseRateLyrDefineParamVo.setCustNo(businessSceneInfoVo.getCustNo()); // 客户号=In.客户号
            baseRateLyrDefineParamVo.setAccountNo(businessSceneInfoVo.getAccountNo()); // 账号=In.客户账号
            // 根据条件计算得到收费金额(访问基础费率分层定义信息计算)
            ResultVo<FeeCalculateResultVo> feeAmountResultVo = baseRateLyrDefineService
                    .getFeeAmountInnerByCondition(baseRateLyrDefineParamVo, pricingChargeParamVo);
            if (!feeAmountResultVo.getResultCode().equals("00000")) {
                throw new BizException(feeAmountResultVo.getResultCode(), feeAmountResultVo.getResultMsg());
            }
            if (StringUtils.isEmpty(feeAmountResultVo) || StringUtils.isEmpty(feeAmountResultVo.getData())
                    || StringUtils.isEmpty(feeAmountResultVo.getData().getFeeCode())) {
                tipMsg = "[没有获取到基础费率信息]";
                logger.info("[根据条件计算得到收费金额(访问基础费率分层定义信息计算),没有获取到数据]!");
                throw new BizException("90001", tipMsg);
            }
            FeeCalculateResultVo feeCalculateResultVo = feeAmountResultVo.getData();
            BigDecimal feeAmount = feeCalculateResultVo.getFeeAmount(); // 收费金额
            /**
             * 如果in. 批量收费笔数>1并且out.费用代码[n]=’0000000001’ ,则 赋值out.收费金额[n] =
             * BFEPCLFE.收费金额*in. 批量收费笔数 否则 赋值out.收费金额[n] = BFEPCLFE.收费金额 (新增方法)
             */
            if (!StringUtils.isEmpty(businessSceneInfoVo.getBatchChargeNum())) {
                if (businessSceneInfoVo.getBatchChargeNum() > 1
                        && prpFeeCfrmRuleResultVo.getFeeCode().equals("0000000001")) {
                    // 赋值out.收费金额[n] = BFEPCLFE.收费金额*in. 批量收费笔数
                    feeAmount = feeAmount.multiply(new BigDecimal(businessSceneInfoVo.getBatchChargeNum()));
                }
            }
            totalFeeAmount = totalFeeAmount.add(feeAmount);
            chargeFeeResultVo = new ChargeFeeResultVo();
            chargeFeeResultVo.setFeeCode(prpFeeCfrmRuleResultVo.getFeeCode()); // 费用代码
            chargeFeeResultVo.setFeeAmount(feeAmount); // 收费金额
            chargeFeeResultVo.setJzsfAmount(feeCalculateResultVo.getJzsfAmount());// out.基准收费金额[n]=BFEPCLFE.基准收费金额
            chargeFeeResultVo.setYhsfAmount(feeCalculateResultVo.getYhsfAmount());// out.优惠收费金额[n]=BFEPCLFE.优惠收费金额
            chargeFeeResultVo.setXysfAmount(feeCalculateResultVo.getXysfAmount());// out.协议收费金额[n]=BFEPCLFE.协议收费金额
            chargeFeeResultVo.setSxcl(feeCalculateResultVo.getSxcl()); // out.筛选策略[n]=BFEPCLFE.筛选策略
            chargeFeeResultVo.setZzsfAmount(feeAmount); // out.最终收费金额[n]=BFEPCLFE.收费金额
            chargeFeeResultVoList.add(chargeFeeResultVo);
        }
        // 设置返回的结果
        pricingChargeResultVo.setChargeFeeResultVoList(chargeFeeResultVoList);
        pricingChargeResultVo.setTotalFeeAmount(totalFeeAmount);
        resultVo.setData(pricingChargeResultVo);
        /**
         * 如果试算和计收费标志=2，则继续3.4处理，否则结束程序
         */
        if (pricingChargeParamVo.getChargeFlag() == 1) {
            return resultVo;
        }
        /**
         * 3.4. 循环进行收费处理，调用BFEPCHG“收费处理”构件
         */
        for (ChargeFeeResultVo chargeFeeResultVo2 : chargeFeeResultVoList) {
            PricingAmountProcessParamVo pricingAmountProcessParamVo = new PricingAmountProcessParamVo();
            pricingAmountProcessParamVo.setFeeCode(chargeFeeResultVo2.getFeeCode());// 费种代码=out.费种代码[n]
            pricingAmountProcessParamVo.setFeeAmount(chargeFeeResultVo2.getFeeAmount());// 收费金额=out.收费金额[n]
            pricingAmountProcessParamVo.setCurrencyCode(jiFeiItemVo.getBillgCcyCode()); // 收费币种=In.交易币种
            pricingAmountProcessParamVo.setAccountOrgNo(businessSceneInfoVo.getTransOrgNo()); // 记账机构=In.交易发起机构
            pricingAmountProcessParamVo.setTransDate(businessSceneInfoVo.getTransDate()); // 交易日期=In.交易日期
            pricingAmountProcessParamVo.setTransTime(businessSceneInfoVo.getTransTime()); // 交易时间=In.交易时间
            pricingAmountProcessParamVo.setTransCustNo(businessSceneInfoVo.getTransPersonCode()); // 交易柜员=In.交易柜员
            pricingAmountProcessParamVo.setTransCode(businessSceneInfoVo.getTransCode()); // 交易编号=In.交易编号
            ResultVo<FeeItemResultVo> feeItemResultVo = pricingCommonService
                    .pricingAmountInnerProcess(pricingChargeParamVo, pricingAmountProcessParamVo);
            if (StringUtils.isEmpty(feeItemResultVo) || StringUtils.isEmpty(feeItemResultVo.getData())) {
                tipMsg = "[收费处理,计算增值税金额失败]";
                logger.info(tipMsg);
                throw new BizException("90001", tipMsg);
            }
            FeeItemResultVo feeItemVo = feeItemResultVo.getData();
            chargeFeeResultVo.setZzsAmount(feeItemVo.getZzsAmount());
            chargeFeeResultVo.setShAmount(feeItemVo.getShAmount());
            chargeFeeResultVo2.setZzsAmount(feeItemVo.getZzsAmount());
            chargeFeeResultVo2.setShAmount(feeItemVo.getShAmount());
            totalZzsAmount = totalZzsAmount.add(chargeFeeResultVo.getZzsAmount());
            totalShAmount = totalShAmount.add(chargeFeeResultVo.getShAmount());
        }
        // 设置返回的结果
        pricingChargeResultVo.setChargeFeeResultVoList(chargeFeeResultVoList); // 收费信息VoList
        pricingChargeResultVo.setTotalFeeAmount(totalFeeAmount); // 总收费金额
        pricingChargeResultVo.setTotalZzsAmount(totalZzsAmount); // 总增值税金额
        pricingChargeResultVo.setTotalShAmount(totalShAmount); // 总税后收费金额
        resultVo.setData(pricingChargeResultVo);
        // 返回结果
        return resultVo;
    }

}
